package com.fanrenqiji.common.web;

import java.beans.PropertyEditorSupport;
import java.sql.SQLException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.validation.ConstraintViolationException;
import javax.validation.Validator;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ui.Model;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import com.fanrenqiji.common.beanvalidator.BeanValidators;
import com.fanrenqiji.common.utils.StringUtils;

/**
 * @author lijian E-mail:ljz0721cx@163.com
 * @version 创建时间：2015年1月21日 下午12:38:09
 * @description 控制器支持类
 */
public abstract class BaseController {
	/**
	 * 日志对象
	 */
	protected Logger logger = LoggerFactory.getLogger(getClass());
	/**
	 * 验证Bean实例对象
	 */
	@Autowired
	protected Validator validator;

	/**
	 * 服务端参数有效性验证
	 * 
	 * @param object
	 *            验证的实体对象
	 * @param groups
	 *            验证组
	 * @return 验证成功：返回true；严重失败：将错误信息添加到 message 中
	 */
	protected boolean beanValidator(Model model, Object object,
			Class<?>... groups) {
		try {
			BeanValidators.validateWithException(validator, object, groups);
		} catch (ConstraintViolationException ex) {
			List<String> list = BeanValidators.extractPropertyAndMessageAsList(
					ex, ": ");
			list.add(0, "数据验证失败：");
			addMessage(model, list.toArray(new String[] {}));
			return false;
		}
		return true;
	}
	
	
	/**
	 * 服务端参数有效性验证
	 * 
	 * @param object
	 *            验证的实体对象
	 * @param groups
	 *            验证组
	 * @param msg
	 *            逻辑错误提示消息
	 * @return 验证成功：返回true；严重失败：将错误信息添加到 message 中
	 */
	protected boolean beanValidator(String msg,Model model, Object object,
			Class<?>... groups) {
		try {
			BeanValidators.validateWithException(validator, object, groups);
		} catch (ConstraintViolationException ex) {
			List<String> list = BeanValidators.extractPropertyAndMessageAsList(
					ex, ": ");
			list.add(0, "数据验证失败：");
			if(StringUtils.isNotEmpty(msg)) {
				list.add(msg);
			}
			addMessage(model, list.toArray(new String[] {}));
			return false;
		}
		return true;
	}

	/**
	 * 服务端参数有效性验证
	 * 
	 * @param object
	 *            验证的实体对象
	 * @param groups
	 *            验证组
	 * @return 验证成功：返回true；严重失败：将错误信息添加到 flash message 中
	 */
	protected boolean beanValidator(RedirectAttributes redirectAttributes,
			Object object, Class<?>... groups) {
		try {
			BeanValidators.validateWithException(validator, object, groups);
		} catch (ConstraintViolationException ex) {
			List<String> list = BeanValidators.extractPropertyAndMessageAsList(
					ex, ": ");
			list.add(0, "数据验证失败：");
			addMessage(redirectAttributes, list.toArray(new String[] {}));
			return false;
		}
		return true;
	}

	/**
	 * 添加Model消息
	 * 
	 * @param messages
	 */
	protected void addMessage(Model model, String... messages) {
		StringBuilder sb = new StringBuilder();
		for (String message : messages) {
			sb.append(message).append(messages.length > 1 ? "<br/>" : "");
		}
		model.addAttribute("message", sb.toString());
	}

	/**
	 * 添加Flash消息
	 * 
	 * @param messages
	 */
	protected void addMessage(RedirectAttributes redirectAttributes,
			String... messages) {
		StringBuilder sb = new StringBuilder();
		for (String message : messages) {
			sb.append(message).append(messages.length > 1 ? "<br/>" : "");
		}
		redirectAttributes.addFlashAttribute("message", sb.toString());
	}

	/**
	 * 日期类型解析绑定到实体数据中
	 * 
	 * @param binder
	 */
	@InitBinder
	public void initBinder(WebDataBinder binder) {
		binder.registerCustomEditor(Date.class,  new PropertyEditorSupport() {  
			SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
	        @Override  
	        public void setAsText(String text) throws IllegalArgumentException { 
	        	if (!org.springframework.util.StringUtils.hasText(text)) {
	    			// Treat empty String as null value.
	    			setValue(null);
	    		}
	        	else if (text != null && text.length() <= 0 && text.length() >=20) {
	    			throw new IllegalArgumentException(
	    					"Could not parse date: it is not exactly characters long");
	    		}
	        	else if (text != null && text.length() > 10) {
	        		try {
	        			dateFormat= new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
						setValue(dateFormat.parse(text));
					} catch (ParseException e) {
						e.printStackTrace();
					}
	    		}
	    		else {
	    			try {
	    				setValue(dateFormat.parse(text));
	    			}
	    			catch (ParseException ex) {
	    				throw new IllegalArgumentException("Could not parse date: " + ex.getMessage(), ex);
	    			}
	    		}
	        }  
	        @Override
	    	public String getAsText() {
	    		Date value = (Date) getValue();
	    		return (value != null ? dateFormat.format(value) : "");
	    	}
	    });  
		
	}

	/**
	 * TODO 异常的控制拦截
	 * 
	 * @param request
	 * @param e
	 * @return
	 */
	/*@ExceptionHandler
	public String exception(HttpServletRequest request, Exception e) {
		// 添加自己的异常处理逻辑，如日志记录　　　
		request.setAttribute("exceptionMessage", e.getMessage());
		// 根据不同的异常类型进行不同处理
		if (e instanceof SQLException)
			return "sqlerror";
		else
			return "error";
	}*/
}
